/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * MergeAdvancedPanel.java
 *
 * Created on Sep 19, 2011, 4:42:59 AM
 */
package thesis.view;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.util.HashMap;
import java.util.List;
import java.util.ResourceBundle;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.table.DefaultTableModel;
import util.Config;
import util.DataUtils;
import util.Document;
import util.MathUtils;

/**
 *
 * @author banhbaochay
 */
public class MergeAdvancedPanel extends javax.swing.JPanel {

    private static final int NORMAL_MODE = 0;
    private static final int JSRE_MODE = 1;

    /** Creates new form MergeAdvancedPanel
     * @param mapConfig 
     */
    public MergeAdvancedPanel(HashMap mapConfig) {
        this.path = (String) mapConfig.get(Config.DIRECTORY_PATH);
        rs = ResourceBundle.getBundle("thesis.view.Message");
        trainModel = new DefaultTableModel(
                new Object[][]{},
                new String[]{
                    "File", "Length"
                }) {

            @Override
            public boolean isCellEditable(int row, int column) {
                return false;
            }
        };
        testModel = new DefaultTableModel(
                new Object[][]{},
                new String[]{
                    "File", "Length"
                }) {

            @Override
            public boolean isCellEditable(int row, int column) {
                return false;
            }
        };
        initComponents();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        buttonGroup1 = new javax.swing.ButtonGroup();
        jLabel1 = new javax.swing.JLabel();
        dirPathTf = new javax.swing.JTextField();
        refreshButton = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        trainTable = new javax.swing.JTable();
        jScrollPane2 = new javax.swing.JScrollPane();
        testTable = new javax.swing.JTable();
        rightButton = new javax.swing.JButton();
        leftButton = new javax.swing.JButton();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        totalTrainLabel = new javax.swing.JLabel();
        totalTestLabel = new javax.swing.JLabel();
        runButton = new javax.swing.JButton();
        jLabel6 = new javax.swing.JLabel();
        trainTf = new javax.swing.JTextField();
        browseTrainButton = new javax.swing.JButton();
        jLabel7 = new javax.swing.JLabel();
        testTf = new javax.swing.JTextField();
        browseTestButton = new javax.swing.JButton();
        browseDirButton = new javax.swing.JButton();
        jLabel4 = new javax.swing.JLabel();
        normalButton = new javax.swing.JRadioButton();
        jsreButton = new javax.swing.JRadioButton();

        jLabel1.setText("Path:");
        jLabel1.setName("jLabel1"); // NOI18N

        dirPathTf.setName("dirPathTf"); // NOI18N
        dirPathTf.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                dirPathTfActionPerformed(evt);
            }
        });

        refreshButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/thesis/view/resources/icons/refresh32.png"))); // NOI18N
        refreshButton.setName("refreshButton"); // NOI18N
        refreshButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                refreshButtonActionPerformed(evt);
            }
        });

        jScrollPane1.setName("jScrollPane1"); // NOI18N

        trainTable.setModel(trainModel);
        trainTable.setName("trainTable"); // NOI18N
        trainTable.setSelectionMode(javax.swing.ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        jScrollPane1.setViewportView(trainTable);

        jScrollPane2.setName("jScrollPane2"); // NOI18N

        testTable.setModel(testModel);
        testTable.setName("testTable"); // NOI18N
        testTable.setSelectionMode(javax.swing.ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        jScrollPane2.setViewportView(testTable);

        rightButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/thesis/view/resources/icons/right_arrow32.png"))); // NOI18N
        rightButton.setName("rightButton"); // NOI18N
        rightButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                rightButtonActionPerformed(evt);
            }
        });

        leftButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/thesis/view/resources/icons/left_arrow32.png"))); // NOI18N
        leftButton.setName("leftButton"); // NOI18N
        leftButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                leftButtonActionPerformed(evt);
            }
        });

        jLabel2.setText("Total:");
        jLabel2.setName("jLabel2"); // NOI18N

        jLabel3.setText("Total:");
        jLabel3.setName("jLabel3"); // NOI18N

        totalTrainLabel.setText("0 line(s)");
        totalTrainLabel.setName("totalTrainLabel"); // NOI18N

        totalTestLabel.setText("0 line(s)");
        totalTestLabel.setName("totalTestLabel"); // NOI18N

        runButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/thesis/view/resources/icons/run.png"))); // NOI18N
        runButton.setName("runButton"); // NOI18N
        runButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                runButtonActionPerformed(evt);
            }
        });

        jLabel6.setText("Save train file to:");
        jLabel6.setName("jLabel6"); // NOI18N

        trainTf.setName("trainTf"); // NOI18N

        browseTrainButton.setText("...");
        browseTrainButton.setName("browseTrainButton"); // NOI18N
        browseTrainButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                browseTrainButtonActionPerformed(evt);
            }
        });

        jLabel7.setText("Save test file to:");
        jLabel7.setName("jLabel7"); // NOI18N

        testTf.setName("testTf"); // NOI18N

        browseTestButton.setText("...");
        browseTestButton.setName("browseTestButton"); // NOI18N
        browseTestButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                browseTestButtonActionPerformed(evt);
            }
        });

        browseDirButton.setText("...");
        browseDirButton.setName("browseDirButton"); // NOI18N
        browseDirButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                browseDirButtonActionPerformed(evt);
            }
        });

        jLabel4.setText("Mode:");
        jLabel4.setName("jLabel4"); // NOI18N

        buttonGroup1.add(normalButton);
        normalButton.setSelected(true);
        normalButton.setText("normal");
        normalButton.setName("normalButton"); // NOI18N
        normalButton.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                normalButtonItemStateChanged(evt);
            }
        });

        buttonGroup1.add(jsreButton);
        jsreButton.setText("JSRE");
        jsreButton.setName("jsreButton"); // NOI18N
        jsreButton.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                jsreButtonItemStateChanged(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(95, 95, 95)
                .addComponent(jLabel1)
                .addGap(18, 18, 18)
                .addComponent(dirPathTf, javax.swing.GroupLayout.PREFERRED_SIZE, 426, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(browseDirButton)
                .addGap(18, 18, 18)
                .addComponent(refreshButton)
                .addGap(192, 192, 192))
            .addGroup(layout.createSequentialGroup()
                .addGap(69, 69, 69)
                .addComponent(jLabel2)
                .addGap(106, 106, 106)
                .addComponent(totalTrainLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 292, Short.MAX_VALUE)
                .addComponent(jLabel3)
                .addGap(137, 137, 137)
                .addComponent(totalTestLabel)
                .addGap(124, 124, 124))
            .addGroup(layout.createSequentialGroup()
                .addGap(23, 23, 23)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 388, Short.MAX_VALUE)
                        .addGap(18, 18, 18)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(runButton)
                            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                                .addComponent(leftButton)
                                .addComponent(rightButton)))
                        .addGap(6, 6, 6))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel6)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(trainTf, javax.swing.GroupLayout.PREFERRED_SIZE, 187, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(browseTrainButton)
                        .addGap(81, 81, 81)))
                .addGap(12, 12, 12)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 374, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel7)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(testTf, javax.swing.GroupLayout.PREFERRED_SIZE, 187, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(browseTestButton)))
                .addGap(19, 19, 19))
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap(359, Short.MAX_VALUE)
                .addComponent(jLabel4)
                .addGap(18, 18, 18)
                .addComponent(normalButton)
                .addGap(18, 18, 18)
                .addComponent(jsreButton)
                .addGap(353, 353, 353))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(26, 26, 26)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel4)
                    .addComponent(normalButton)
                    .addComponent(jsreButton))
                .addGap(12, 12, 12)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(18, 18, 18)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel1)
                            .addComponent(dirPathTf, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(browseDirButton)))
                    .addComponent(refreshButton))
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(27, 27, 27)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 327, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 327, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(18, 18, 18)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(totalTestLabel)
                            .addComponent(jLabel2)
                            .addComponent(jLabel3)
                            .addComponent(totalTrainLabel)))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(113, 113, 113)
                        .addComponent(rightButton)
                        .addGap(18, 18, 18)
                        .addComponent(leftButton)))
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel6)
                            .addComponent(trainTf, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(browseTrainButton))
                        .addGap(18, 18, 18)
                        .addComponent(runButton))
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(jLabel7)
                        .addComponent(testTf, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(browseTestButton)))
                .addGap(36, 36, 36))
        );
    }// </editor-fold>//GEN-END:initComponents

    private void refreshButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_refreshButtonActionPerformed
        // TODO add your handling code here:
        String dirPath = dirPathTf.getText();
        if (dirPath.equals("")) {
            JOptionPane.showMessageDialog(null, rs.getString("empty.path"),
                    "Warning", JOptionPane.WARNING_MESSAGE);
            return;
        }// end if path

        File dir = new File(dirPath);
//        if (!dir.exists()) {
//            File curDir = new File(".");
//            String curDirPath = curDir.getAbsolutePath().replaceFirst("\\.$", "");
//
//            dir = new File(curDirPath + dirPath);
//
//            if (!dir.isDirectory()) {
//                JOptionPane.showMessageDialog(null, rs.getString("invalid.path"),
//                        "Warning", JOptionPane.WARNING_MESSAGE);
//                return;
//            }// end if dir is directory
//
//        }// end dir exist
        
        if (!dir.exists() || !dir.isDirectory()) {
            JOptionPane.showMessageDialog(null, rs.getString("invalid.path"),
                    "Warning", JOptionPane.WARNING_MESSAGE);
            return;
        }// end if empty or not directory

        File[] files = dir.listFiles(new FilenameFilter() {

            public boolean accept(File dir, String name) {
                return name.matches(".*\\.txt");
            }
        });

        if (files.length != 0) {
            for (File file : files) {
                Document doc = new Document(file);
                trainModel.addRow(new Object[]{doc, doc.size()});
                updateLabels();
            }// end foreach file
        } else {
            JOptionPane.showMessageDialog(null, rs.getString("no.file.in.dir"), "Warning", JOptionPane.INFORMATION_MESSAGE);
        }// end if files.length

    }//GEN-LAST:event_refreshButtonActionPerformed

    private void browseDirButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseDirButtonActionPerformed
        // TODO add your handling code here:
        JFileChooser fc = new JFileChooser(path);
        fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        int f = fc.showOpenDialog(this);
        if (f == JFileChooser.APPROVE_OPTION) {
            dirPathTf.setText(fc.getSelectedFile().getAbsolutePath());
        }// end if f == JFileChooser.APPROVE_OPTION
    }//GEN-LAST:event_browseDirButtonActionPerformed

    private void browseTrainButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseTrainButtonActionPerformed
        // TODO add your handling code here:
        JFileChooser fc = new JFileChooser(path);
        int f = fc.showSaveDialog(this);
        if (f == JFileChooser.APPROVE_OPTION) {
            trainTf.setText(fc.getSelectedFile().getAbsolutePath());
        }// end if f == JFileChooser.APPROVE_OPTION
    }//GEN-LAST:event_browseTrainButtonActionPerformed

    private void browseTestButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseTestButtonActionPerformed
        // TODO add your handling code here:
        JFileChooser fc = new JFileChooser(path);
        int f = fc.showSaveDialog(this);
        if (f == JFileChooser.APPROVE_OPTION) {
            testTf.setText(fc.getSelectedFile().getAbsolutePath());
        }// end if f == JFileChooser.APPROVE_OPTION
    }//GEN-LAST:event_browseTestButtonActionPerformed

    /**
     * Cap nhat lai cac nhan ve tong so cau trong tung bang train va test
     */
    public void updateLabels() {
        int totalTrain = MathUtils.calcLength(trainTable, MathUtils.NORMAL_MODE);
        int totalTest = MathUtils.calcLength(testTable, MathUtils.NORMAL_MODE);
        totalTrainLabel.setText(totalTrain + " line(s)");
        totalTestLabel.setText(totalTest + " line(s)");
    }// end updateLabels method

    private void runButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_runButtonActionPerformed
        // TODO add your handling code here:

        if (trainTf.getText().equals("") || testTf.getText().equals("")) {
            JOptionPane.showMessageDialog(null, rs.getString("empty.path"), "Error", JOptionPane.ERROR_MESSAGE);
            return;
        }// end if empty trainTf or testTf

        List trainList = DataUtils.getDataColFromTable(trainTable, 0);
        List testList = DataUtils.getDataColFromTable(testTable, 0);

        if (mode == NORMAL_MODE) {
            // che do thuong, cac thanh phan du lieu deu la doi tuong Document
            Document trainDoc = new Document();
            for (Object child : trainList) {
                Document doc = (Document) child;
                trainDoc.append(doc);
            }// end foreach doc
            try {
                trainDoc.print2File(trainTf.getText());
            } catch (FileNotFoundException ex) {
                JOptionPane.showMessageDialog(null, rs.getString("can.not.save"), "Error", JOptionPane.ERROR_MESSAGE);
            }// end try

            Document testDoc = new Document();
            for (Object child : testList) {
                Document doc = (Document) child;
                testDoc.append(doc);
            }// end foreach doc
            try {
                testDoc.print2File(testTf.getText());
            } catch (FileNotFoundException ex) {
                JOptionPane.showMessageDialog(null, rs.getString("can.not.save"), "Error", JOptionPane.ERROR_MESSAGE);
            }// end try
        } else {
            // che do jsre, cac thanh phan du lieu deu la doi tuong JSREDocument
        }

        JOptionPane.showMessageDialog(null, rs.getString("save.success"), "Message", JOptionPane.INFORMATION_MESSAGE);

    }//GEN-LAST:event_runButtonActionPerformed

    private void normalButtonItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_normalButtonItemStateChanged
        // TODO add your handling code here:
        if (normalButton.isSelected()) {
            mode = NORMAL_MODE;
        }
    }//GEN-LAST:event_normalButtonItemStateChanged

    private void jsreButtonItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_jsreButtonItemStateChanged
        // TODO add your handling code here:
        if (jsreButton.isSelected()) {
            mode = JSRE_MODE;
        }
    }//GEN-LAST:event_jsreButtonItemStateChanged

    /**
     * CHuyen cac file select tu table train sang test
     * @param evt 
     */
    private void rightButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rightButtonActionPerformed
        // TODO add your handling code here:
        int val = DataUtils.moveRows(trainTable, testTable);
        if (val == 0) {
            JOptionPane.showMessageDialog(null, rs.getString("no.selected.row"), "Warning", JOptionPane.WARNING_MESSAGE);
        } else {
            updateLabels();
        }
    }//GEN-LAST:event_rightButtonActionPerformed

    /**
     * Chuyen cac file select tu table test sang train
     * @param evt 
     */
    private void leftButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_leftButtonActionPerformed
        // TODO add your handling code here:
        int val = DataUtils.moveRows(testTable, trainTable);
        if (val == 0) {
            JOptionPane.showMessageDialog(null, rs.getString("no.selected.row"), "Warning", JOptionPane.WARNING_MESSAGE);
        } else {
            updateLabels();
        }
    }//GEN-LAST:event_leftButtonActionPerformed

    private void dirPathTfActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dirPathTfActionPerformed
        // TODO add your handling code here:
        refreshButtonActionPerformed(evt);
    }//GEN-LAST:event_dirPathTfActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton browseDirButton;
    private javax.swing.JButton browseTestButton;
    private javax.swing.JButton browseTrainButton;
    private javax.swing.ButtonGroup buttonGroup1;
    private javax.swing.JTextField dirPathTf;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JRadioButton jsreButton;
    private javax.swing.JButton leftButton;
    private javax.swing.JRadioButton normalButton;
    private javax.swing.JButton refreshButton;
    private javax.swing.JButton rightButton;
    private javax.swing.JButton runButton;
    private javax.swing.JTable testTable;
    private javax.swing.JTextField testTf;
    private javax.swing.JLabel totalTestLabel;
    private javax.swing.JLabel totalTrainLabel;
    private javax.swing.JTable trainTable;
    private javax.swing.JTextField trainTf;
    // End of variables declaration//GEN-END:variables
    private DefaultTableModel trainModel;
    private DefaultTableModel testModel;
    private String path;
    private ResourceBundle rs;
    // Che do lam viec cua chuong trinh, hoac normal hoac JSRE
    private int mode;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
                HashMap mapConfig = new HashMap();
                MergeAdvancedPanel p = new MergeAdvancedPanel(mapConfig);
                frame.add(p);
                frame.pack();
                frame.setVisible(true);
            }
        });
    }// end main class
}
